package config

import (
	"fmt"
	"os"
	"strconv"
	"time"

	"github.com/joho/godotenv"
)

var appConfig *Config

// Config 应用配置
type Config struct {
	Server    ServerConfig
	Database  DatabaseConfig
	Redis     RedisConfig
	JWT       JWTConfig
	Websocket WebsocketConfig
	Seckill   SeckillConfig
}

// ServerConfig 服务器配置
type ServerConfig struct {
	Host string
	Port int
	Mode string
}

// DatabaseConfig 数据库配置
type DatabaseConfig struct {
	Host     string
	Port     int
	User     string
	Password string
	DBName   string
	MaxIdle  int
	MaxOpen  int
}

// RedisConfig Redis配置
type RedisConfig struct {
	Host     string
	Port     int
	Password string
	DB       int
	PoolSize int
}

// JWTConfig JWT配置
type JWTConfig struct {
	Secret string
	Expire time.Duration
}

// WebsocketConfig WebSocket配置
type WebsocketConfig struct {
	ReadBufferSize  int
	WriteBufferSize int
	CheckOrigin     bool
}

// SeckillConfig 秒杀配置
type SeckillConfig struct {
	LockTimeout    time.Duration
	LuaScriptPath  string
	ScanInterval   int
	NotifyAdvance  int
	MaxConcurrency int
}

// LoadConfig 加载配置
func LoadConfig(envPath string) (*Config, error) {
	if err := godotenv.Load(envPath); err != nil {
		fmt.Printf("加载.env文件失败: %v，使用默认值\n", err)
	}

	config := &Config{
		Server: ServerConfig{
			Host: getEnv("SERVER_HOST", "0.0.0.0"),
			Port: getEnvAsInt("SERVER_PORT", 8080),
			Mode: getEnv("SERVER_MODE", "debug"),
		},
		Database: DatabaseConfig{
			Host:     getEnv("DB_HOST", "localhost"),
			Port:     getEnvAsInt("DB_PORT", 3306),
			User:     getEnv("DB_USER", "root"),
			Password: getEnv("DB_PASSWORD", ""),
			DBName:   getEnv("DB_NAME", "seckill"),
			MaxIdle:  getEnvAsInt("DB_MAX_IdLE", 10),
			MaxOpen:  getEnvAsInt("DB_MAX_OPEN", 100),
		},
		Redis: RedisConfig{
			Host:     getEnv("REDIS_HOST", "localhost"),
			Port:     getEnvAsInt("REDIS_PORT", 6379),
			Password: getEnv("REDIS_PASSWORD", ""),
			DB:       getEnvAsInt("REDIS_DB", 0),
			PoolSize: getEnvAsInt("REDIS_POOL_SIZE", 100),
		},
		JWT: JWTConfig{
			Secret: getEnv("JWT_SECRET", "secretKey"),
			Expire: time.Hour * 24,
		},
		Websocket: WebsocketConfig{
			ReadBufferSize:  getEnvAsInt("WS_READ_BUFFER_SIZE", 1024),
			WriteBufferSize: getEnvAsInt("WS_WRITE_BUFFER_SIZE", 1024),
			CheckOrigin:     getEnvAsBool("WS_CHECK_ORIGIN", true),
		},
		Seckill: SeckillConfig{
			LockTimeout:    time.Duration(getEnvAsInt("LOCK_TIMEOUT", 5)) * time.Second,
			LuaScriptPath:  getEnv("LUA_SCRIPT_PATH", "seckill.lua"),
			ScanInterval:   getEnvAsInt("SCAN_INTERVAL", 60),
			NotifyAdvance:  getEnvAsInt("NOTIFY_ADVANCE", 1),
			MaxConcurrency: getEnvAsInt("MAX_CONCURRENCY", 1000),
		},
	}

	appConfig = config
	return config, nil
}

// GetConfig 获取全局配置
func GetConfig() *Config {
	if appConfig == nil {
		config, _ := LoadConfig(".env")
		return config
	}
	return appConfig
}

// getEnv 获取环境变量，如果不存在则返回默认值
func getEnv(key, defaultValue string) string {
	if value := os.Getenv(key); value != "" {
		return value
	}
	return defaultValue
}

// getEnvAsInt 获取环境变量作为整数
func getEnvAsInt(key string, defaultValue int) int {
	valueStr := getEnv(key, "")
	if value, err := strconv.Atoi(valueStr); err == nil {
		return value
	}
	return defaultValue
}

// getEnvAsBool 获取环境变量作为布尔值
func getEnvAsBool(key string, defaultValue bool) bool {
	valueStr := getEnv(key, "")
	if value, err := strconv.ParseBool(valueStr); err == nil {
		return value
	}
	return defaultValue
}
